// 用于管理游戏中的请求队列，根据请求的优先级将其分配到即时队列或批量队列，并按顺序处理这些请求
export class GameRequestQueue {
  private immediateQueue: Array<{ action: string, priority: number, data: any }> = []; // 即时队列，存储高优先级请求,每个元素是包含动作和优先级的对象(如刹车、氮气等)
  private batchQueue: Map<string, any[]> = new Map(); // 批量队列,键为动作名，值为请求数据数组(如聊天消息)
  private isSending = false; // 标志位，指示是否正在发送请求，避免并发处理队列

  // 动态优先级计算
  private getPriority(action: string, gameState: any): number {
    // 定义动作与优先级的映射表
    const priorityMap: Record<string, number> = {
      'Light': 100,  // 高亮最高优先级
      'MOVE': 95,   // 移动
      'NITRO': 90,   // 氮气加速
      'STEER': 70,   // 转向
      'CHAT': 10     // 聊天消息
    };
    // 如果比赛结束，优先级减半
    return priorityMap[action] * (gameState.isRaceEnded ? 0.5 : 1);
  }

  // 向队列中添加请求，根据优先级分配到不同队列
  addRequest(action: string, data: any, gameState: any) {
    const priority = this.getPriority(action, gameState);

    if (priority > 50) {
      // 高优先级请求添加到即时队列，并按优先级降序排序
      this.immediateQueue.push({ action, priority, data });
      this.immediateQueue.sort((a, b) => b.priority - a.priority); // 降序排序
    } else {
      // 低优先级请求添加到批量队列
      if (!this.batchQueue.has(action)) {
        this.batchQueue.set(action, []);
      }
      this.batchQueue.get(action)!.push(data);
    }
    // 处理队列
    this.processQueue();
  }

  // 处理队列:先处理即时队列，再处理批量队列
  private async processQueue() {
    // 如果正在发送请求，直接返回
    if (this.isSending) return;
    this.isSending = true;

    // 优先发送即时队列
    while (this.immediateQueue.length > 0) {
      const { action, data } = this.immediateQueue.shift()!;
      await this.sendToServer(action, data);
    }

    // 合并批量队列
    const batchData: Record<string, any[]> = {};
    this.batchQueue.forEach((values, key) => {
      batchData[key] = values;
    });
    this.batchQueue.clear();
    // 发送批量请求
    if (Object.keys(batchData).length > 0) {
      await this.sendToServer('BATCH', batchData);
    }
    // 标记请求处理完成
    this.isSending = false;
  }

  private async sendToServer(action: string, data?: any) {
    // 实际网络请求逻辑
    console.log(`发送: ${action}`, data);
  }
}

// 根据比赛阶段动态调整
function getDynamicPriority(basePriority: number, gameState: any) {
  let multiplier = 1;

  // 最后冲刺阶段提升操作优先级
  if (gameState.remainingLaps === 1) multiplier *= 1.5;

  // 玩家排名影响聊天消息优先级
  if (gameState.playerRank > 3) multiplier *= 0.8;

  // 网络延迟补偿
  if (gameState.networkLatency > 200) multiplier *= 1.2;

  return Math.floor(basePriority * multiplier);
}

const requestList = [{
  url: '/api/request',
  data: { text: 'hello world1' },
}, {
  url: '/api/request',
  data: { text: 'hello world2' },
}, {
  url: '/api/request',
  data: { text: 'hello world3' },
}, {
  url: '/api/request',
  data: { text: 'hello world4' },
}, {
  url: '/api/request',
  data: { text: 'hello world5' },
}, {
  url: '/api/request',
  data: { text: 'hello world6' },
}, {
  url: '/api/request',
  data: { text: 'hello world7' },
}, {
  url: '/api/request',
  data: { text: 'hello world8' },
}, {
  url: '/api/request',
  data: { text: 'hello world9' },
}, {
  url: '/api/request',
  data: { text: 'hello world10' },
}, {
  url: '/api/request',
  data: { text: 'hello world11' },
}]

const testPromises = () => {
  const requestPromise: any[] = [];
  requestList.forEach((item) => {
    requestPromise.push(fetch(item.url, { method: 'POST', body: JSON.stringify(item.data) }))
  })
  // Promise.all (适合独立请求)
  Promise.all(requestPromise)
    .then(([userRes, postsRes]) => {
      console.log(userRes.data, postsRes.data);
    })
    .catch(error => {
      console.error('任一请求失败', error);
    });

  // Promise.allSettled (需处理部分失败)
  Promise.allSettled(requestPromise)
    .then(results => {
      results.forEach(result => {
        if (result.status === 'fulfilled') {
          console.log('成功:', result.value);
        } else {
          console.error('失败:', result.reason);
        }
      });
    });
}
// testPromises()

// 顺序请求处理 (适合依赖关系)
const sequentialRequests = async () => {
  const results = [];

  for (const url of requestList) {
    const res: any = await fetch(url, { method: 'GET' });
    results.push(res.data);
  }

  console.log(results);

}
// sequentialRequests()